using System;
using System.Collections.Generic;
using System.IO;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using LitJson;
using UnityEngine;
using UnityEngine.Networking;

namespace HsVoice
{
    [Obsolete("弃用但留着,功能迁移到HsSynthWS")]
    public class HsSynthClient
    {
        private const int BUFFER_SIZE = 52_4288;
        private byte[] reqHeader = { 0x11, 0x10, 0x11, 0x00 };
        private ClientWebSocket webSocket;
        private CancellationToken ct;
        private SHsSynth sHsSynth;
        public HsSynthHandle handle;
   
        public HsSynthClient()
        {
            handle = new HsSynthHandle();
            sHsSynth = new SHsSynth();
            sHsSynth.Clear();
        }

        public void OpenTTS()
        {
            sHsSynth.Clear();
            handle.NewTaskUid();
            Connect();
        }
        

        public async void StopTTS()
        {
            if(webSocket!=null)
                webSocket.Dispose();
        }

        public async void Synth(int id ,HsSynthRequest request)
        {
            handle.taskid = id;
            byte[] body = JsonMapper.ToJson(request).ToBytes().ToGzip();
            byte[] bodyLen = body.Length.ToBytes().ToBitEndian();
            byte[] req = reqHeader.MergeBytes(bodyLen, body);
            await webSocket.SendAsync(new ArraySegment<byte>(req), WebSocketMessageType.Binary, true, new CancellationToken());
        }


        private async void Connect()
        {
            webSocket = new ClientWebSocket();
            webSocket.Options.SetRequestHeader("Authorization", "Bearer; " + HsApp.APP_TOKEN);
            Uri uri = new Uri(HsApp.WSS_SYNTHESIZER);
            ct = new CancellationToken();
            await webSocket.ConnectAsync(uri, ct);
            Debug.Log($"[ 连接火山引擎智能语音... ] : {webSocket.State}");
            Receive(ct);
        }

        private async void Receive(CancellationToken token)
        {
            while (webSocket.State == WebSocketState.Open)
            {
                try
                {
                    byte[] readData = new byte[BUFFER_SIZE];
                    var res = await webSocket.ReceiveAsync(new Memory<byte>(readData), token);
                    byte[] realData = readData.Sclie(res.Count);
                    OnMessage(realData);
                }
                catch
                {
                }
            }
            Debug.Log("断开连接");
        }

        private async void OnMessage(byte[] buffer)
            {
                //int protocolVersion = (buffer[0] & 0xff) >> 4;  //暂时没使用，注释掉减少计算量
                //int headerSize = buffer[0] & 0x0f;              //暂时没使用，注释掉减少计算量
                int messageType = (buffer[1] & 0xff) >> 4;
                int messageTypeSpecificFlags = buffer[1] & 0x0f;
                //int serializationMethod = (buffer[2] & 0xff) >> 4; //暂时没使用，注释掉减少计算量
                //int messageCompression = buffer[2] & 0x0f;  //暂时没使用，注释掉减少计算量
                //int reserved = buffer[3] & 0xff;   //暂时没使用，注释掉减少计算量
                byte[] payload = buffer.SclieFormIndex(4);

                switch (messageType)
                {
                    case HsApp.SYNTH_SUCCRSS:
                        if (messageTypeSpecificFlags == 0)
                        {
                            //服务器相应标志，不需要处理
                            // Debug.Log($"[火山引擎语音合成 服务器相应]");
                        }
                        else
                        {
                            try
                            {
                                int sequenceNumber = payload.Sclie(0, 4).BytesToInt32();
                                //int payloadSize = payload.Sclie(4, 4).ToLittleEndian().BytesToInt32(); //暂时没使用，注释掉减少计算量
                                byte[] audioData = payload.SclieFormIndex(8);
                                sHsSynth.payload.Add(audioData);
                                handle.Write(audioData);
                                if (sequenceNumber < 0)
                                {
                                    sHsSynth.isEnd = true;
                                    handle.DisposeStream();
                                    handle.LoadAudio();
                                    StopTTS();
                                    Debug.Log($"[火山引擎语音合成 完成~] :{sHsSynth.AudioBytes().Length} ");
                                }
                            }
                            catch (Exception e)
                            {
                                Debug.Log(e.Message);
                                StopTTS();
                            }
                        }

                        break;
                    case HsApp.SYNTH_ERROR:
                        int errorCode = payload.Sclie(0, 4).ToLittleEndian().BytesToInt32();
                        Debug.Log($"[火山引擎语音合成 错误码] : {errorCode}");
                        StopTTS();
                        break;
                    case HsApp.SYNTH_UNKOWN:

                        break;
                }
            }
        }
    }